using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
    private CharacterController characterController;
    float horizontal;
    float vertical;
    [Header("碰撞")]
    private CollisionFlags m_CollisionFlags; // 碰撞标记
    [Header("移动")]
    public float Speed = 10f; // 玩家移动的速度
    public Vector3 velocity = Vector3.zero; // 角色的当前速度

    [Header("旋转")]
    public float RotateSpeed = 30f; // 玩家旋转的速度

    [Header("跳跃")]
    public float JumpHeight = 3f;//跳跃高度
    public float Gravity = -39.8f;//重力

    [Header("地面检测")]
    public bool isGround;

    void Start()
    {
        characterController = GetComponent<CharacterController>(); // 初始化角色控制器
    }

    void Update()
    {
        // 获取输入
        horizontal = Input.GetAxis("Horizontal");
        vertical = Input.GetAxis("Vertical");

        // 处理角色旋转
        if (horizontal != 0)
        {
            transform.Rotate(Vector3.up * horizontal * RotateSpeed * Time.deltaTime);
        }

        // 处理角色移动
        Vector3 move = transform.forward * Speed * vertical;
        m_CollisionFlags = characterController.Move(move * Time.deltaTime);

        // 跳跃处理
        if (isGround && Input.GetButtonDown("Jump"))
        {
            velocity.y = Mathf.Sqrt(JumpHeight * -2 * Gravity);
        }

        // 应用重力
        m_CollisionFlags = characterController.Move(velocity * Time.deltaTime);
        //地面检测
        isGround = characterController.isGrounded;
        if (isGround)
        {
            // 当isGrounded为true时，将Y轴方向的速度设为了一个较小的负值，这是为了确保能稳定触碰地面，避免isGrounded误判为false
            velocity.y = -2f;
        }
        else
        {
            // 更新重力影响的速度
            velocity.y += Gravity * Time.deltaTime;
        }
    }

    //物理碰撞
    private void OnControllerColliderHit(ControllerColliderHit hit)
    {
        //获取碰撞体上的 Rigidbody 组件。
        Rigidbody body = hit.rigidbody;
        //检查获取到的 Rigidbody 是否为空或者是否为静态物体（isKinematic）
        if (body == null || body.isKinematic)
        {
            return;
        }
        //CollisionFlags.Below 表示角色控制器与碰撞体之间是底部接触
        if (m_CollisionFlags == CollisionFlags.Below)
        {
            return;
        }
        // 在碰撞点施加冲量 ForceMode.Impulse:添加一个瞬间的冲击力到刚体，且自动应用它的质量
        body.AddForceAtPosition(characterController.velocity * 0.1f, hit.point, ForceMode.Impulse);
    }
}
